package com.example.interceptor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.example.dao.ADao;

@Aspect
@Component
public class ControllerInterceptor {

	@Resource
	private ADao adao;
	
	@Pointcut("execution(* com.example.controller.AController.*(..))")
	public void webLog () {
	}

	@Around("webLog()") 
	public Object interceptor (ProceedingJoinPoint pjp) throws Throwable {
		/*
		 * 需要完成的功能：
		 * 	1、获取方法的注解
		 * 	2、获取返回类型
		 * 		1）T
		 * 		2）List<T>，并获取泛型
		 * 		3）Map<String, Object>
		 * 	3、获取方法名
		 * 	4、获取方法参数
		 * 	5、
		 */
		method1(pjp);
		Object result = method2(pjp);
		method3(pjp);
		method4(pjp);
		
		return result;
	}

	private void method1(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println(pjp.getSignature());
		
	}
	
	private Object method2(ProceedingJoinPoint pjp) throws Throwable {
		Object result = pjp.proceed();
		if (result instanceof Map) {
			@SuppressWarnings("unchecked")
			Map<? super Object, ? super Object> map = (Map<? super Object, ? super Object>) result;
			map.put("new key", "new value");
		}
		if (result instanceof List) {
			@SuppressWarnings("unchecked")
			List<? super Object> list = (List<? super Object>) result;
			for (Object item : list) {
				System.out.println(item.getClass());
			}
		}
		System.out.println(result.getClass().getTypeName());
		return result;
	}
	
	private void method3(ProceedingJoinPoint pjp) throws Throwable {
		Signature sig = pjp.getSignature();
		MethodSignature msig = null;
		if (!(sig instanceof MethodSignature)) {
			throw new IllegalArgumentException("该注解只能用于方法");
		}
		msig = (MethodSignature) sig;
		Object target = pjp.getTarget();
		Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
		System.out.println("currentMethod: " + currentMethod.getName());
	}

	private void method4(ProceedingJoinPoint pjp) throws Throwable {
		for (Object params : pjp.getArgs()) {
			System.out.println(params);
		}
	}
}
